import { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons';
import { Input } from 'antd';
import React from 'react';

export interface NumInputProp {
  disabled?: boolean;
  max?: number;
  min?: number;
  step?: number;
  value?: number | '';
  placeholder?: string;
  onChange?: (val: number | undefined) => any;
}

export interface NumInputState extends NumInputProp {}

export class NumInput extends React.Component<NumInputProp, NumInputState> {
  constructor(prop: NumInputProp) {
    super(prop);
    this.state = {
      onChange: prop.onChange,
      disabled: prop.disabled || false,
      max: prop.max,
      min: prop.min,
      step: prop.step || 1,
      value: prop.value,
      placeholder: prop.placeholder || undefined,
    };
  }

  private onInput(e: React.ChangeEvent<HTMLInputElement>): void {
    const oldVal = parseInt(e.target.value || '0');
    this.setState(
      {
        value: this.verifyVal(oldVal) || '',
      },
      () => {
        const state = this.state;
        state.onChange && state.onChange(state.value as number);
      }
    );
  }

  private verifyVal(val: string | number): number | undefined {
    if (isNaN(val as number)) {
      return;
    }
    const { max, min } = this.state;
    let newVal = parseInt(val as string);
    if (max != null) {
      newVal > max && (newVal = max);
    }
    if (min != null) {
      newVal < min && (newVal = min);
    }
    return newVal;
  }

  private add(): void {
    const oldVal = this.state.value || 0;
    const fakeEvent = {
      target: {
        value: oldVal + 1,
      },
    } as any;
    this.onInput(fakeEvent);
  }

  private reducing(): void {
    const oldVal = this.state.value || 0;
    const fakeEvent = {
      target: {
        value: oldVal - 1,
      },
    } as any;
    this.onInput(fakeEvent);
  }

  public getValue(): number | undefined | '' {
    return this.state.value;
  }

  render() {
    const { disabled, value, placeholder } = this.state;
    const iconStyle = {
      fontSize: '20px',
      color: '#40a9ff',
      transform: 'translateY(5px)',
    };

    return (
      <div className="num-input">
        <MinusCircleOutlined style={{ ...iconStyle }} onClick={() => this.reducing()} />
        <Input
          className="num-input-inputer"
          value={value}
          onInput={e => {
            this.setState({ value: (e.target as any).value });
          }}
          onBlur={e => {
            this.onInput(e);
          }}
          disabled={disabled}
          placeholder={placeholder}
        />
        <PlusCircleOutlined style={{ ...iconStyle }} onClick={() => this.add()} />
      </div>
    );
  }
}
